package com.ssy.lingxi.workflow.serviceimpl;

import com.ssy.lingxi.workflow.entity.ExternalTaskDefinition;
import com.ssy.lingxi.workflow.model.constant.ModelConstant;
import com.ssy.lingxi.workflow.model.constant.ProcessTaskTypeEnum;
import com.ssy.lingxi.workflow.repository.ExternalTaskRepository;
import com.ssy.lingxi.workflow.service.IExternalTaskDaoService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 外部任务Dao接口实现类型，使用了Redis缓存
 * @author 万宁
 * @version 2.0.0
 * @date 2021-04-26
 */
@Service
public class ExternalTaskDaoServiceImpl implements IExternalTaskDaoService {
    @Resource
    private ExternalTaskRepository externalTaskRepository;

    @Resource
    private RedisTemplate<String, List<ExternalTaskDefinition>> redisTemplate;

    /**
     * 删除流程
     * @param processKey 流程Key
     */
    @Override
    public void deleteByProcessKey(String processKey) {
        externalTaskRepository.deleteByProcessKey(processKey);
        redisTemplate.delete(ModelConstant.PROCESS_CACHE_KEY.concat(processKey));
    }

    /**
     * 保存流程
     *
     * @param processKey              流程Key
     * @param externalTaskDefinitions 流程任务列表
     */
    @Override
    public void saveAll(String processKey, List<ExternalTaskDefinition> externalTaskDefinitions) {
        externalTaskRepository.saveAll(externalTaskDefinitions);
        redisTemplate.opsForValue().set(ModelConstant.PROCESS_CACHE_KEY.concat(processKey), externalTaskDefinitions);
    }

    /**
     * 查询流程任务
     *
     * @param processKey 流程Key
     * @return 任务列表
     */
    @Override
    public List<ExternalTaskDefinition> findByProcessKey(String processKey) {
        List<ExternalTaskDefinition> externalTaskDefinitions = redisTemplate.opsForValue().get(ModelConstant.PROCESS_CACHE_KEY.concat(processKey));
        if(!CollectionUtils.isEmpty(externalTaskDefinitions)) {
            return externalTaskDefinitions;
        }

        externalTaskDefinitions = externalTaskRepository.findByProcessKey(processKey);

        redisTemplate.opsForValue().set(ModelConstant.PROCESS_CACHE_KEY.concat(processKey), externalTaskDefinitions);

        return externalTaskDefinitions;
    }

    /**
     * 查询启动节点
     *
     * @param processKey 流程的Key
     * @return 流程启动节点
     */
    @Override
    public ExternalTaskDefinition findStartEvent(String processKey) {
        List<ExternalTaskDefinition> externalTaskDefinitions = findByProcessKey(processKey);
        if(!CollectionUtils.isEmpty(externalTaskDefinitions)) {
            ExternalTaskDefinition starterTask = externalTaskDefinitions.stream().filter(externalTask -> externalTask.getTaskType().equals(ProcessTaskTypeEnum.START_EVENT.getCode())).findFirst().orElse(null);
            return Objects.nonNull(starterTask) ? starterTask : externalTaskRepository.findFirstByProcessKeyAndTaskType(processKey, ProcessTaskTypeEnum.START_EVENT.getCode());
        }

        return externalTaskRepository.findFirstByProcessKeyAndTaskType(processKey, ProcessTaskTypeEnum.START_EVENT.getCode());
    }

    /**
     * 查找外部任务节点
     *
     * @param processKey 流程Key
     * @param taskName   外部任务名称
     * @param taskType   任务类型
     * @return 外部任务定义
     */
    @Override
    public List<ExternalTaskDefinition> findByProcessKeyAndTaskNameAndTaskType(String processKey, String taskName, Integer taskType) {
        List<ExternalTaskDefinition> externalTaskDefinitions = findByProcessKey(processKey);
        if(!CollectionUtils.isEmpty(externalTaskDefinitions)) {
            return externalTaskDefinitions.stream().filter(externalTask -> externalTask.getTaskName().equals(taskName) && externalTask.getTaskType().equals(taskType)).collect(Collectors.toList());
        }

        return externalTaskRepository.findByProcessKeyAndTaskNameAndTaskType(processKey, taskName, taskType);
    }
}
